package com.linq.cool.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.linq.cool.api.domain.SysRole;
import com.linq.cool.api.domain.SysUser;
import com.linq.cool.api.vo.SysUserVO;
import com.linq.cool.common.core.exception.BusinessException;
import com.linq.cool.common.core.utils.BeanUtils;
import com.linq.cool.common.core.utils.SecurityUtils;
import com.linq.cool.common.core.utils.StringUtils;
import com.linq.cool.common.datascope.annotation.DataScope;
import com.linq.cool.system.domain.SysPost;
import com.linq.cool.system.domain.SysUserPost;
import com.linq.cool.system.domain.SysUserRole;
import com.linq.cool.system.dto.SysUserAddDTO;
import com.linq.cool.system.dto.SysUserQueryDTO;
import com.linq.cool.system.dto.SysUserUpdateDTO;
import com.linq.cool.system.mapper.SysUserMapper;
import com.linq.cool.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author: yqlin
 * @Date: 2020/12/29 19:13
 * @Description:
 * @Version: 1.0.0
 */
@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysUserPostService sysUserPostService;
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private SysPostService sysPostService;

    @DataScope(deptAlias = "d", userAlias = "u")
    @Override
    public IPage<SysUserVO> listByPage(IPage<SysUserVO> page, SysUserQueryDTO dto) {
        log.info("获取到listByPage-->params:{}", dto.getParams());
        return baseMapper.listByPage(page, dto);
    }


    @Override
    public SysUserVO getByUsername(String username) {
        return baseMapper.getByUsername(username);
    }

    @Override
    public SysUser getById(Long userId) {
        return baseMapper.getById(userId);
    }

    @Override
    public boolean checkUsernameUnique(String username) {
        // 查询该用户使用的人数 如果>0就已经使用过了
        // select count(*) from sys_user where  username = #{username}
        int count = this.count(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username));
        // 存在:1 不存在:0
        return count > 0;

    }

    @Override
    public boolean checkPhoneUnique(SysUser user) {
        // 判断传入的是否是空(新增或者更细) 新增的时候id roleId=-1  更新就是原来的
        Long userId = null == user.getId() ? -1L : user.getId();
        SysUser one = this.getOne(new LambdaQueryWrapper<SysUser>()
                                          .select(SysUser::getId, SysUser::getPhone)
                                          .eq(SysUser::getPhone, user.getPhone())
        );
        // 判断id是否一致 不一致就代表 唯一 false
        return null != one && !userId.equals(one.getId());
    }

    @Override
    public boolean checkEmailUnique(SysUser user) {
        // 判断传入的是否是空(新增或者更细) 新增的时候id roleId=-1  更新就是原来的
        Long userId = null == user.getId() ? -1L : user.getId();
        SysUser one = this.getOne(new LambdaQueryWrapper<SysUser>()
                                          .select(SysUser::getId, SysUser::getEmail)
                                          .eq(SysUser::getEmail, user.getEmail())
        );
        // 判断id是否一致 不一致就代表 唯一 false
        return null != one && !userId.equals(one.getId());
    }

    @Override
    public void checkAllowed(SysUser user) {
        // 判断是否是管理员 不允许操作超级管理员用户
        if (StringUtils.isNotNull(user.getId()) && user.isAdmin()) {
            throw new BusinessException("不允许操作超级管理员用户");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateUser(SysUserUpdateDTO dto) {
        SysUser user = new SysUser();
        BeanUtils.copyProperties(dto, user);
        this.checkAllowed(user);
        if (StringUtils.isNotEmpty(user.getPhone()) && this.checkPhoneUnique(user)) {
            throw new BusinessException("修改用户'" + user.getUsername() + "'失败，手机号码已存在");
        }
        if (StringUtils.isNotEmpty(user.getEmail()) && this.checkEmailUnique(user)) {
            throw new BusinessException("修改用户'" + user.getUsername() + "'失败，邮箱账号已存在");
        }
        user.setModifier(SecurityUtils.getUserId()).setGmtModified(new Date());
        this.updateById(user);
        Long userId = user.getId();
        // 删除用户与角色关联
        sysUserRoleService.remove(new LambdaQueryWrapper<SysUserRole>()
                                          .eq(SysUserRole::getUserId, userId)
        );
        // 新增用户与角色管理
        this.saveUserRole(userId, dto.getRoleIds());
        // 删除用户与岗位关联
        sysUserPostService.remove(new LambdaQueryWrapper<SysUserPost>()
                                          .eq(SysUserPost::getUserId, userId)
        );
        // 新增用户与岗位管理
        return this.saveUserPost(userId, dto.getPostIds());

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteByIds(List<Long> userIds) {
        // 循环判断 该用户是否是超级管理员 如果不是才可以进行 删除
        userIds.forEach(uid -> {
            this.checkAllowed(new SysUser(uid));
        });
        // 批量逻辑删除
        return this.removeByIds(userIds);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveUser(SysUserAddDTO dto) {
        if (this.checkUsernameUnique(dto.getUsername())) {
            throw new BusinessException("新增用户'" + dto.getUsername() + "'失败，登录账号已存在");
        }
        SysUser user = new SysUser();
        BeanUtils.copyProperties(dto, user);
        if (StringUtils.isNotEmpty(dto.getPhone()) && this.checkPhoneUnique(user)) {
            throw new BusinessException("新增用户'" + user.getUsername() + "'失败，手机号码已存在");
        }
        if (StringUtils.isNotEmpty(user.getEmail()) && this.checkEmailUnique(user)) {
            throw new BusinessException("新增用户'" + user.getUsername() + "'失败，邮箱账号已存在");
        }
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        user.setCreator(SecurityUtils.getUserId());
        // 新增用户信息
        this.save(user);
        // 新增用户与角色管理
        this.saveUserRole(user.getId(), dto.getRoleIds());
        // 新增用户和岗位管理
        return this.saveUserPost(user.getId(), dto.getPostIds());
    }

    @Override
    public String getRoleGropByUserId(Long userId) {
        List<SysRole> list = sysRoleService.listRolesByUserId(userId);
        StringBuilder idsStr = new StringBuilder();
        for (SysRole role : list) {
            idsStr.append(role.getName()).append(",");
        }
        if (StringUtils.isNotEmpty(idsStr.toString())) {
            return idsStr.substring(0, idsStr.length() - 1);
        }
        return idsStr.toString();
    }

    @Override
    public String getPostGropByUserId(Long userId) {
        List<SysPost> list = sysPostService.listPostsByUserId(userId);
        StringBuilder idsStr = new StringBuilder();
        for (SysPost post : list) {
            idsStr.append(post.getName()).append(",");
        }
        if (StringUtils.isNotEmpty(idsStr.toString())) {
            return idsStr.substring(0, idsStr.length() - 1);
        }
        return idsStr.toString();
    }

    private boolean saveUserPost(Long userId, List<Long> postIds) {
        boolean flag = false;
        if (StringUtils.isNotNull(postIds)) {
            // 新增用户与岗位管理
            List<SysUserPost> list = new ArrayList<>();
            postIds.forEach(id -> {
                SysUserPost up = new SysUserPost();
                up.setUserId(userId).setPostId(id);
                list.add(up);
            });
            if (list.size() > 0) {
                // 批量新增岗位信息
                if (sysUserPostService.saveBatch(list)) {
                    flag = true;
                }
            }
        }
        return flag;
    }

    private void saveUserRole(Long userId, List<Long> roleIds) {
        if (StringUtils.isNotNull(roleIds)) {
            // 新增用户与角色管理
            List<SysUserRole> list = new ArrayList<>();
            roleIds.forEach(id -> {
                SysUserRole ur = new SysUserRole();
                ur.setUserId(userId).setRoleId(id);
                list.add(ur);
            });
            if (list.size() > 0) {
                // 批量新增用户角色信息
                sysUserRoleService.saveBatch(list);
            }
        }
    }
}

